package v1

import (
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"zimuzu_cvn_web_api/config"
	"zimuzu_cvn_web_api/model"
	. "zimuzu_cvn_web_api/pkg/e"
	"zimuzu_cvn_web_api/pkg/errno"
	"zimuzu_cvn_web_api/router/api"
	"zimuzu_cvn_web_api/router/api/app/middleware"
	"zimuzu_cvn_web_api/service"
)

type PassportAPI struct {
}

func (passport PassportAPI) Name() string {
	return "passport API"
}

func (passport PassportAPI) Bind() {
	passportAPI := config.C.Router.Group("/v1/app/passport", middleware.TrackLog())
	{
		passportAPI.POST("login", login)
		passportAPI.POST("reg", reg)
		passportAPI.POST("inviteReg", inviteReg)
		passportAPI.POST("verifyRegCode", verifyRegCode)
	}
	passport2API := config.C.Router.Group("/v1/app/passport", middleware.TrackLog(), middleware.AuthMiddleware())
	{
		passport2API.GET("init", loginInit)
		passport2API.GET("loginOut", loginOut)
	}
}

type loginParams struct {
	Account string `form:"account" json:"account" binding:"required"`
	Pwd     string `form:"pwd" json:"pwd" binding:"required"`
	Area    int    `form:"area" json:"area" binding:"required"`
}

//登录提交
//Auth: Xu
func login(c *gin.Context) {
	var params loginParams
	err := c.ShouldBindWith(&params, binding.FormPost)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}

	//test := strings.Split("11", "|")

	//reg := regexp.MustCompile("[^\u4E00-\u9FA5\\w]")
	//if reg.MatchString(params.Pwd) {
	//	fmt.Println("[Err] YYets Password Check: Error 1")
	//	api.SendResponse(c, errors.New("1111"), nil)
	//	return
	//}
	//return

	if !IsPhone(params.Account) {
		api.SendResponse(c, errors.New("请输入正确格式的手机号"), nil)
		return
	}
	loginIp := c.ClientIP()
	var user model.User
	user, checkloginErr := service.CheckLogin(params.Account, params.Pwd, params.Area)
	if checkloginErr != nil {
		if user.Uid != 0 {
			service.AddLoginErrCount(loginIp, user.Uid)
		}
		api.SendResponse(c, checkloginErr, nil)
		return
	}
	hasPayPassword := 1
	if res, err := service.CheckPayPasswordExist(user.Uid); err == nil && res {
		hasPayPassword = 2
	}

	token := service.CreateToken(service.LoginPlatformApp, user.Uid, user.Password, user.Nickname)
	shopToken := service.GetShopTokenCache(user.Uid)
	responseData := map[string]interface{}{
		"uid":            user.Uid,
		"hasPayPassword": hasPayPassword,
		"shop_token":     shopToken,
		"token":          token,
	}

	errno.OK.Info = "用户登录成功"
	api.SendResponse(c, errno.OK, responseData)
	return

}

//登录检查
//Auth: Xu
func loginInit(c *gin.Context) {
	uid, _ := service.GetUserIdByRequest(c)
	userInfo, err := service.GetUserInfo(uid)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}
	hasPayPassword := 1
	if res, err := service.CheckPayPasswordExist(uid); err == nil && res {
		hasPayPassword = 2
	}
	responseData := map[string]interface{}{
		"hasPayPassword": hasPayPassword,
		"nickname":       userInfo.Nickname,
		"mobile":         userInfo.PhoneNumber,
	}
	api.SendResponse(c, errno.OK, responseData)
	return
}

type verifyRegCodeParam struct {
	Mobile string `form:"mobile" json:"mobile" binding:"required"`
	Code   int    `form:"code" json:"code" binding:"required"`
	Area   int    `form:"area" json:"area" binding:"required"`
}

//提交验证码
//Auth: Xu
func verifyRegCode(c *gin.Context) {
	var params verifyRegCodeParam
	err := c.ShouldBindWith(&params, binding.FormPost)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}
	if errValid := service.ValidateCode(params.Mobile, service.SendCodeSceneReg, params.Code); errValid != nil {
		api.SendResponse(c, errValid, nil)
		return
	}
	uid, err := service.GetInviteUidByMobile(params.Mobile, params.Area)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}
	sign := service.CreateRegSign(params.Mobile)
	responseData := make(map[string]string)
	responseData["sign"] = sign
	responseData["invitationCode"] = uid

	errno.OK.Info = "验证通过"
	api.SendResponse(c, errno.OK, responseData)
}

type regParams struct {
	Mobile         string `form:"mobile" json:"mobile" binding:"required"`
	Pwd            string `form:"pwd" json:"pwd" binding:"required"`
	Pwdconfirm     string `form:"pwdconfirm" json:"pwdconfirm" binding:"required"`
	NickName       string `form:"nickname" json:"nickname" binding:"required"`
	Area           int    `form:"area" json:"area"`
	Sign           string `form:"sign" json:"sign" binding:"required"`
	InvitationCode string `form:"invitationCode" json:"invitationCode"`
}

//注册提交
//Auth: Xu
func reg(c *gin.Context) {
	var params regParams
	err := c.ShouldBindWith(&params, binding.FormPost)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}

	//验证签名
	if err := service.ValidateRegSign(params.Mobile, params.Sign); err != nil {
		api.SendResponse(c, err, nil)
		return
	}

	user, errCreate := service.Register(params.Mobile, params.Area, params.Pwd, params.Pwdconfirm, params.NickName, c.ClientIP(), 15)
	if errCreate != nil {
		api.SendResponse(c, errCreate, nil)
		return
	}
	//更新被邀请人的uid
	if len(params.InvitationCode) != 0 {
		if err := service.UpdateUidByMobile(params.InvitationCode, params.Mobile, params.Area, user.Uid); err != nil {
			api.SendResponse(c, err, nil)
			return
		}
	}

	//注册后直接登陆
	token := service.CreateToken(service.LoginPlatformApp, user.Uid, user.Password, user.Nickname)
	shopToken := service.GetShopTokenCache(user.Uid)
	responseData := map[string]interface{}{
		"uid":        user.Uid,
		"shop_token": shopToken,
		"token":      token,
	}

	errno.OK.Info = "注册成功"
	api.SendResponse(c, errno.OK, responseData)
	return

}

/*
 * @ Author: hupfei
 * @ Description: 3.2.7 填写邀请码时注册
 **/
type inviteRegParams struct {
	Phone          string `form:"phone" binding:"required"`
	Pwd            string `form:"pwd" binding:"required"`
	NickName       string `form:"nickname" binding:"required"`
	Area           int    `form:"area" binding:"required"`
	Sign           string `form:"sign" binding:"required"`
	InvitationCode int64  `form:"invitationCode" binding:"required"`
	Source         int    `form:"source" json:"source"` //0 返佣邀请 1 矿工邀请
}

func inviteReg(c *gin.Context) {
	var params inviteRegParams
	err := c.ShouldBindWith(&params, binding.FormPost)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}

	//验证签名
	if err := service.ValidateRegSign(params.Phone, params.Sign); err != nil {
		api.SendResponse(c, err, nil)
		return
	}

	user, errCreate := service.Register(params.Phone, params.Area, params.Pwd, params.Pwd, params.NickName, c.ClientIP(), 17)
	if errCreate != nil {
		api.SendResponse(c, errCreate, nil)
		return
	}

	//注册完后接受邀请
	p := model.AcceptInviteParams{
		Code:      params.InvitationCode,
		PhoneArea: params.Area,
		Phone:     params.Phone,
		Source:    params.Source,
	}
	re, info, err := service.FillInInviteCode(user.Uid, p)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}
	errno.OK.Info = info
	api.SendResponse(c, errno.OK, re)
	return
}

type loginOutParams struct {
	Uid       int64  `form:"uid" json:"uid" binding:"required"`
	ShopToken string `form:"shop_token" json:"shop_token"`
}

//退出登录
//Auth: Xu
func loginOut(c *gin.Context) {
	var params loginOutParams
	err := c.ShouldBindWith(&params, binding.Query)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}
	uid, _ := service.GetUserIdByRequest(c)
	err = service.LoginOutClearToken(uid, service.LoginPlatformApp)
	if err != nil {
		api.SendResponse(c, errors.New("退出登录失败"), nil)
		return
	}

	errno.OK.Info = "退出登录成功"
	api.SendResponse(c, errno.OK, nil)
	return
}
